/**
 * Copyright (c) 2018-2022, NXOS Development Team
 * SPDX-License-Identifier: Apache-2.0
 * 
 * Contains: Kernel exposed object to user
 * 
 * Change Logs:
 * Date           Author            Notes
 * 2022-4-30      JasonHu           Init
 */

#ifndef __EXPOSED_OBJECT_H__
#define __EXPOSED_OBJECT_H__

#include <nxos_mini.h>
#include <base/spin.h>

/**
 * Maximum number of supported objects
 */
#define NX_EXOBJ_MAX_NR 4096

/**
 * Number of objects added each time
 */
#define NX_EXOBJ_APPEND_NR 32

/**
 * Initial number of objects
 */
#define NX_EXOBJ_INIT_NR NX_EXOBJ_APPEND_NR

#define NX_SOLT_INVALID_VALUE -1

typedef int NX_Solt;

typedef enum NX_ExposedObjectType
{
    NX_EXOBJ_NONE = 0,
    NX_EXOBJ_RESERVERD, /* reserved obj */
    NX_EXOBJ_THREAD,
    NX_EXOBJ_SNAPSHOT,
    NX_EXOBJ_MUTEX,
    NX_EXOBJ_SEMAPHORE,
    NX_EXOBJ_DEVICE,
    NX_EXOBJ_TIMER,
    NX_EXOBJ_UDRIVER,
    NX_EXOBJ_HUB,
    NX_EXOBJ_SHM,
    NX_EXOBJ_SHMADDR,
    NX_EXOBJ_FILE,
    NX_EXOBJ_DIR,
    NX_EXOBJ_IPC,
    NX_EXOBJ_IPC_CHANNEL,
    NX_EXOBJ_FIFO,
    NX_EXOBJ_CONDITION,
    NX_EXOBJ_MSGQUEUE,
    NX_EXOBJ_PIPE,
    NX_EXOBJ_UOBJECT, /* user object */
    NX_EXOBJ_TRACER,
    NX_EXOBJ_TYPE_NR,
} NX_ExposedObjectType;

typedef NX_Error (*NX_SoltCloseHandler)(void * object, NX_ExposedObjectType type);
typedef NX_Error (*NX_SoltCopyHandler)(void * object, NX_ExposedObjectType type);

typedef struct NX_ExposedObject
{
    void * object;
    NX_ExposedObjectType type;
    NX_SoltCloseHandler close;
    NX_SoltCopyHandler copy;
    NX_Atomic reference;
} NX_ExposedObject;

#define NX_EXOBJ_OBJPTR_SIZE sizeof(NX_ExposedObject *)

typedef struct NX_ExposedObjectTable
{
    NX_ExposedObject **objectArray;
    NX_Size usedCount;
    NX_Size maxCount;
    NX_Spin lock;
} NX_ExposedObjectTable;

typedef struct NX_UserObject {
    void *object;
    NX_U32 pid;
} NX_UserObject;

NX_Error NX_ExposedObjectTableInit(NX_ExposedObjectTable * table);
NX_Error NX_ExposedObjectTableExit(NX_ExposedObjectTable * table);
NX_Error NX_ExposedObjectTableDump(NX_ExposedObjectTable * table);

NX_ExposedObject * NX_ExposedObjectGet(NX_ExposedObjectTable * table, NX_Solt solt);
NX_Solt NX_ExposedObjectLocate(NX_ExposedObjectTable * table, void * object, NX_ExposedObjectType type);

NX_Error NX_ExposedObjectInstall(NX_ExposedObjectTable * table, void * object, NX_ExposedObjectType type, NX_SoltCloseHandler handler,
    NX_SoltCloseHandler copyHandler, NX_Solt * outSolt);
NX_Error NX_ExposedObjectUninstalll(NX_ExposedObjectTable * table, NX_Solt solt);

NX_Error NX_ExposedObjectCopy(NX_ExposedObjectTable * dst, NX_ExposedObjectTable * src, NX_Solt solt, NX_Solt * outSolt);
NX_Error NX_ExposedObjectCopyTo(NX_ExposedObjectTable * dst, NX_ExposedObjectTable * src, NX_Solt destSolt, NX_Solt srcSolt);

const char * NX_ExposedObjectGetNameByType(NX_ExposedObjectType type);

NX_UserObject *NX_UserObjectCreate(void *object, NX_U32 pid);
NX_Error NX_UserObjectDestroy(NX_UserObject *object);

#endif  /* __EXPOSED_OBJECT_H__ */